<?php

namespace App\Common\Helpers;

use Mine\MineModel;
use Mine\MineRequest;

class SortHelper
{
    private $model = null;
    private $where = [];
    private $sortField = 'sort';

    public function __construct($class,$where = [],$field = 'sort')
    {
        $this -> model = new $class;
        $this -> where = $where;
        $this -> sortField = $field;
    }

    /**
     * 排序处理
     * @param $direction
     * down    下移
     * up      上移
     * top     置顶
     * bottom  置底
     * exchange  交换
     * @param $id
     * @param $otherId
     */
    public function process($direction,$id,$otherId)
    {
        switch ($direction){
            case 'down':
                $this -> sortAfter($id);
                break;
            case 'up':
                $this -> sortPre($id);
                break;
            case 'top':
                $this -> sortTop($id);
                break;
            case 'bottom':
                $this -> sortBottom($id);
                break;
            case 'exchange':
                $this -> exchangePosition($id,$otherId);
                break;
        }
    }

    /**
     * 置顶
     * @param $id
     */
    private function sortTop($id){
        $maxSort = $this -> model -> newQuery() ->  where($this -> where) -> max($this -> sortField);
        $this -> model -> newQuery() -> where('id',$id) -> update([$this -> sortField => $maxSort + 1]);
    }

    /**
     * 置底
     * @param $id
     */
    private function sortBottom($id)
    {
        $minSort = $this -> model -> newQuery() ->  where($this -> where) -> min($this -> sortField);
        $this -> model -> newQuery() -> where('id',$id) -> update([$this -> sortField => $minSort - 1]);
    }

    /**
     * 上移
     * @param $id
     */
    private function sortPre($id)
    {
        $thisSort = $this -> model -> newQuery() ->  where('id',$id) -> value($this -> sortField);
        $preId = $this -> model -> newQuery() ->  where($this -> where) -> where($this -> sortField,'>=',$thisSort) -> where('id','<>',$id) -> min('id');
        $preId && $this -> exchangePosition($id,$preId);
    }

    /**
     * 下移
     * @param $id
     */
    private function sortAfter($id)
    {
        $thisSort = $this -> model -> newQuery() ->  where('id',$id) -> value($this -> sortField);
        $afterId = $this -> model -> newQuery() ->  where($this -> where) -> where($this -> sortField,'<=',$thisSort) -> where('id','<>',$id) -> max('id');
        $afterId && $this -> exchangePosition($id,$afterId);
    }


    /**
     * 交换位置
     * @param $nowId
     * @param $otherId
     * @return false
     */
    private function exchangePosition($nowId,$otherId)
    {
        if($nowId == $otherId) return false;
        $nowModel = $this -> model -> newQuery() ->  where('id',$nowId) -> where($this -> where) -> first();
        $otherModel = $this -> model -> newQuery() ->  where('id',$otherId) -> where($this -> where)  -> first();
        if(!empty($nowModel) && !empty($otherModel)){
            $sortField=$this -> sortField;
            $otherSort = $otherModel -> $sortField;
            $nowSort = $nowModel -> $sortField;
            $nowModel -> $sortField = $otherSort;
            $otherModel -> $sortField = $nowSort;
            $nowModel -> save();
            $otherModel -> save();
        }
    }
}